﻿using System.Collections.Generic;
using System.Linq;
using EPiServer.Core;
using EPiServer.DataAccess;
using Xunit;

namespace EPiAbstractions.Fakes.Tests
{
    public class FakePageRepositoryFacts
    {
        [Fact]
        public void GivenNewPage_Save_ReturnsPageReferenceWithPositiveId()
        {
            PageData newPage = new PageData();
            FakePageRepository dataFactory = new FakePageRepository();

            PageReference result = dataFactory.Save(newPage, SaveAction.Save);

            Assert.InRange(result.ID, 1, int.MaxValue);
        }

        [Fact]
        public void WhenNewPageHasBeenSaved_AndGetPageIsCalledWithItsPageReference_GetPageReturnsPageWithSameReference()
        {
            PageData newPage = new PageData();
            FakePageRepository dataFactory = new FakePageRepository();

            PageReference reference = dataFactory.Save(newPage, SaveAction.Save);
            PageData returnedPage = dataFactory.GetPage<PageData>(reference);

            Assert.Equal<PageReference>(reference, returnedPage.PageLink);
        }

        [Fact]
        public void WhenAskedForPageThatHasNotBeenAdded_GetPageReturnsNull()
        {
            FakePageRepository dataFactory = new FakePageRepository();
            PageReference referenceToNotAddedPage = new PageReference(1);

            PageData result = dataFactory.GetPage<PageData>(referenceToNotAddedPage);

            Assert.Null(result);
        }

        [Fact]
        public void NewPagesAreGivenUniqueIds_WhenSaved()
        {
            PageData newPage = new PageData();
            PageData secondNewPage = new PageData();
            FakePageRepository dataFactory = new FakePageRepository();

            PageReference newPagesReference = dataFactory.Save(newPage, SaveAction.Save);
            PageReference secondNewPagesReference = dataFactory.Save(secondNewPage, SaveAction.Save);

            Assert.NotEqual(newPagesReference.ID, secondNewPagesReference.ID);
        }

        [Fact]
        public void WhenSavingExistingPage_ThePageReferenceReturnedIsTheSame()
        {
            PageData newPage = new PageData();
            FakePageRepository dataFactory = new FakePageRepository();
            PageReference referenceAfterFirstSave = dataFactory.Save(newPage, SaveAction.Save);
            PageData existingPage = dataFactory.GetPage<PageData>(referenceAfterFirstSave);

            PageReference referenceAfterSecondSave = dataFactory.Save(existingPage, SaveAction.Save);

            Assert.Equal(referenceAfterFirstSave, referenceAfterSecondSave);
        }

        [Fact]
        public void WhenCalledWithReferenceToParent_GetChildrenReturns_ChildPage()
        {
            PageData parentPage = new PageData();
            FakePageRepository dataFactory = new FakePageRepository();
            PageReference parentReference = dataFactory.Save(parentPage, SaveAction.Save);
            PageData child = new PageData();
            child.Property["PageParentLink"] = new PropertyPageReference(parentReference);

            PageReference childReference = dataFactory.Save(child, SaveAction.Save);
            IEnumerable<PageData> children = dataFactory.GetChildren<PageData>(parentReference);

            Assert.Equal(1, children.Count());
            Assert.Equal(childReference, children.ElementAt(0).PageLink);
        }
    }
}
